#include <string.h>
#include <iostream>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
class String
{
public:
    // 无参构造
    String()
        : m_pstr(new char[1] {}), m_size(0)
    {
    }
    // 有参构造重载
    String(const char* p)
        : m_pstr(new char[strlen(p) + 1] {})
        , m_size(strlen(p))
    {
        if (p)
        {
            strcpy(m_pstr, p);
        }
    }
    // 拷贝构造
    String(const String& rhs)
        : m_pstr(new char[rhs.m_size + 1] {})
        , m_size(rhs.m_size)
    {
        memcpy(m_pstr, rhs.m_pstr, m_size);
    }
    // 析构函数
    ~String()
    {
        if (m_pstr)
        {
            delete[] m_pstr;
            m_pstr = nullptr;
        }
    }
    // 赋值运算符
    String& operator=(const String& rhs)
    {
        // 排除自赋值
        if (this != &rhs)
        {
            delete[] m_pstr;
            m_size = rhs.m_size;
            m_pstr = new char[m_size + 1] {};
            memcpy(m_pstr, rhs.m_pstr, m_size);
        }
        return *this;
    }
    String& operator=(const char* rhs)
    {
        // 排除相同
        int cmp = strncmp(m_pstr, rhs, m_size);
        if (cmp)
        {
            delete[] m_pstr;
            m_size = strlen(rhs);
            m_pstr = new char[m_size + 1] {};
            memcpy(m_pstr, rhs, m_size);
        }
        return *this;
    }

    String& operator+=(const String& rhs)
    {
        size_t temp_size = m_size;
        m_size += rhs.m_size;
        char* temp = new char[m_size + 1] {};
        memcpy(temp, m_pstr, temp_size);
        strncat(temp, rhs.m_pstr, rhs.m_size);
        delete[] m_pstr;
        m_pstr = temp;
        return *this;
    }
    String& operator+=(const char* rhs)
    {
        size_t temp_size = m_size;
        m_size += strlen(rhs);
        char* temp = new char[m_size + 1] {};
        memcpy(temp, m_pstr, temp_size);
        strcat(temp, rhs);
        delete[] m_pstr;
        m_pstr = temp;
        return *this;
    }

    char& operator[](std::size_t index)
    {
        return m_pstr[index];
    }
    const char& operator[](std::size_t index) const
    {
        return m_pstr[index];
    }

    std::size_t size() const {
        return m_size;
    }
    const char* c_str() const {
        return m_pstr;
    }

    friend bool operator==(const String&, const String&);
    friend bool operator!=(const String&, const String&);

    friend bool operator<(const String&, const String&);
    friend bool operator>(const String&, const String&);
    friend bool operator<=(const String&, const String&);
    friend bool operator>=(const String&, const String&);

    friend std::ostream& operator<<(std::ostream& os, const String& s);
    friend std::istream& operator>>(std::istream& is, String& s);

    friend String operator+(const String& lhs, const String& rhs);
    friend String operator+(const String& lhs, const char* rhs);
    friend String operator+(const char* lhs, const String& rhs);

private:
    std::size_t m_size;
    char* m_pstr;
};
bool operator==(const String& lhs, const String& rhs) {
    return !strncmp(lhs.m_pstr, rhs.m_pstr, lhs.m_size);
}
bool operator!=(const String& lhs, const String& rhs) {
    return strncmp(lhs.m_pstr, rhs.m_pstr, lhs.m_size);
}

bool operator<(const String& lhs, const String& rhs) {
    return strncmp(lhs.m_pstr, rhs.m_pstr, lhs.m_size) < 0;
}
bool operator>(const String& lhs, const String& rhs) {
    return strncmp(lhs.m_pstr, rhs.m_pstr, lhs.m_size) > 0;
}
bool operator<=(const String& lhs, const String& rhs) {
    return strncmp(lhs.m_pstr, rhs.m_pstr, lhs.m_size) <= 0;
}
bool operator>=(const String& lhs, const String& rhs) {
    return strncmp(lhs.m_pstr, rhs.m_pstr, lhs.m_size) >= 0;
}

std::ostream& operator<<(std::ostream& os, const String& rhs) {
    for (size_t i = 0; i < rhs.m_size;i++) {
        os << rhs.m_pstr[i];
    }
    return os;
}
std::istream& operator>>(std::istream& is, String& rhs) {
    vector<char> vc;
    char ch;
    while ((ch = is.get()) != '\n' && ch != ' ' && ch != '\t') {
        vc.push_back(ch);
    }
    if (rhs.m_pstr) {
        delete[] rhs.m_pstr;
        rhs.m_pstr = nullptr;
    }
    rhs.m_size = vc.size();
    rhs.m_pstr = new char[rhs.m_size + 1] {};
    memcpy(rhs.m_pstr, &vc[0], rhs.m_size);
    return is;
}

String operator+(const String& lhs, const String& rhs) {
    size_t m_size = lhs.m_size + rhs.m_size;
    char* temp = new char[m_size + 1] {};
    strncat(temp, lhs.m_pstr, lhs.m_size);
    strncat(temp, rhs.m_pstr, rhs.m_size);
    String sr(temp);
    delete[] temp;
    return sr;
}
String operator+(const String& lhs, const char* rhs) {
    size_t m_size = lhs.m_size + strlen(rhs);
    char* temp = new char[m_size + 1] {};
    strncat(temp, lhs.m_pstr, lhs.m_size);
    strncat(temp, rhs, strlen(rhs));
    String sr(temp);
    delete[] temp;
    return sr;
}
String operator+(const char* lhs, const String& rhs) {
    size_t m_size = strlen(lhs) + rhs.m_size;
    char* temp = new char[m_size + 1] {};
    strncat(temp, lhs, strlen(lhs));
    strncat(temp, rhs.m_pstr, rhs.m_size);
    String sr(temp);
    delete[] temp;
    return sr;
}
int main()
{
    String s1 = "hello";
    String s2 = s1;
    s2 += " world";
    cout << s2 << endl;  // 应输出hello world

    String s3;
    cout << "输入字符串:";
    cin >> s3;   // 测试输入包含空格的情况
    cout << s3 << endl;

    String s4 = "hello world";
    cout << s4[4] << endl;  // 应输出h
    s4[4] = '\0';
    cout << s4 << endl;  // 应输出helo


    return 0;
}